/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2005
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
* 
* Author's email :    insane@dees.ufmg.br
* Author's website :  http://www.dees.ufmg.br/insane
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package br.ufmg.dees.insane.ui.rich.full.controller;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

import br.ufmg.dees.insane.commons.controller.Controller;
import br.ufmg.dees.insane.commons.view.DrawingArea;
import br.ufmg.dees.insane.draw.ArrowDraw;
import br.ufmg.dees.insane.draw.ArrowLineDraw;
import br.ufmg.dees.insane.draw.AxisDraw;
import br.ufmg.dees.insane.draw.DisplaceDraw;
import br.ufmg.dees.insane.draw.Draw;
import br.ufmg.dees.insane.draw.LiberationDraw;
import br.ufmg.dees.insane.draw.LineArrowDraw;
import br.ufmg.dees.insane.draw.LineDraw;
import br.ufmg.dees.insane.draw.ParElementDraw;
import br.ufmg.dees.insane.draw.PointDraw;
import br.ufmg.dees.insane.draw.SpringDraw;
import br.ufmg.dees.insane.draw.StringDraw;
import br.ufmg.dees.insane.draw.SupportDraw;
import br.ufmg.dees.insane.materialMedia.material.MSpring;
import br.ufmg.dees.insane.model.Model;
import br.ufmg.dees.insane.model.disc.element.Element;
import br.ufmg.dees.insane.model.disc.element.FrameElement;
import br.ufmg.dees.insane.model.disc.element.ParametricElement;
import br.ufmg.dees.insane.model.disc.element.force.ElementForce;
import br.ufmg.dees.insane.model.disc.element.force.ElementSide;
import br.ufmg.dees.insane.model.disc.element.force.Side;
import br.ufmg.dees.insane.model.disc.fem.FemModel;
import br.ufmg.dees.insane.model.disc.integrationpoint.IntegrationPoint;
import br.ufmg.dees.insane.model.disc.node.Node;
import br.ufmg.dees.insane.model.disc.pointforce.PointForce;
import br.ufmg.dees.insane.ui.rich.full.InsaneInternalInterface;
import br.ufmg.dees.insane.util.IMatrix;
import br.ufmg.dees.insane.util.IPoint3d;
import br.ufmg.dees.insane.util.IVector;


/**
 * @author Fonseca, Flavio & Pitangueira, Roque
 * @since April 2004
 */
public abstract class AttributesController implements Controller {
	
	protected InsaneInternalInterface parent;
	protected Model model;
	protected FemModel fmodel;
	protected DrawingArea da;
	protected ArrayList<Object> selection = new ArrayList<Object>();
	
	protected ArrayList<Draw> nodes = new ArrayList<Draw>();
	protected ArrayList<Draw> felements = new ArrayList<Draw>();
	protected ArrayList<Draw> pelements = new ArrayList<Draw>();
	
	protected ArrayList<Draw> supports = new ArrayList<Draw>();
	protected ArrayList<Draw> springs = new ArrayList<Draw>();
	protected ArrayList<Draw> nodalLoads = new ArrayList<Draw>();
	protected ArrayList<Draw> displaces = new ArrayList<Draw>();
	
	protected ArrayList<Draw> localAxis = new ArrayList<Draw>();
	protected ArrayList<Draw> concForces = new ArrayList<Draw>();
	protected ArrayList<Draw> concForcesPoints = new ArrayList<Draw>();
	protected ArrayList<Draw> liberations = new ArrayList<Draw>();
	protected ArrayList<Draw> preStrains = new ArrayList<Draw>();
	protected ArrayList<Draw> distForces = new ArrayList<Draw>();
	protected ArrayList<Draw> pdistForces = new ArrayList<Draw>();
	protected ArrayList<Draw> tempChanges = new ArrayList<Draw>();
	protected ArrayList<Draw> iniEqForces = new ArrayList<Draw>();
	protected ArrayList<Draw> elasticConnections = new ArrayList<Draw>();
	
	protected ArrayList<Draw> gaussMarks = new ArrayList<Draw>();
	
//*****************************************************************************
	
    /** The constructor method. */
    public AttributesController(Model model, DrawingArea da) {
		this.model = model;
        this.da = da;
        this.fmodel = this.model.getDiscreteModel();
    }
	
//*****************************************************************************
	
	public void setParent(InsaneInternalInterface par) {
		this.parent = par;
	}
	
//*****************************************************************************
	
    public void draw(Graphics2D g) {
        
		double nodeScale = model.getState().nodeScale;
		double supportScale = model.getState().supportScale;
		double loadScale = model.getState().loadScale;
		double displaceScale = model.getState().displaceScale;
		double concForcePointScale = model.getState().concForcePointScale;
		double preStrainsScale = model.getState().preStrainsScale;
		double iniEqForceScale = model.getState().iniEqForceScale;
		
        g.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
		
		Draw draw;
		Node no =null;
		IntegrationPoint ip;
		
		//Draws global axis if selected
		if (model.getState().getViewGlobalAxis()) {
			g.setColor(model.getState().globalAxisColor);
			draw = new AxisDraw();
			((AxisDraw)draw).setLabel1("X");
			((AxisDraw)draw).setLabel2("Y");
			draw.setLocation(new Point(10, da.getHeight()-10));
			draw.draw(g);
		}
		
		//Draws frame elements
		ListIterator lns = felements.listIterator();
		while(lns.hasNext()) {
			g.setColor(model.getState().lineColor);
			draw = (Draw)lns.next();
			draw.draw(g);
		}
		
		//Draws local axis
		if (model.getState().getViewLocalAxis()) {
			ListIterator la = localAxis.listIterator();
			while(la.hasNext()) {
				g.setColor(model.getState().localAxisColor);
				draw = (Draw)la.next();
				draw.draw(g);
			}
		}
		
		//Draws parametric elements
		ParElementDraw eDraw;
		ListIterator els = pelements.listIterator();
		while(els.hasNext()) {
			eDraw = (ParElementDraw)els.next();
			g.setColor( model.getState().parelementColor );
			if ( (((ParametricElement)eDraw.getRepresents()).getMaterial()) != null ) {
				g.setColor(((ParametricElement)eDraw.getRepresents()).getMaterial().getColor() );
			}
			eDraw.draw(g);
		}
		els = pelements.listIterator();
		while(els.hasNext()) {
			eDraw = (ParElementDraw)els.next();
			g.setColor( model.getState().boundaryElementColor );
			eDraw.drawBoundary(g);
			if ( model.getState().getViewElementLabel() ) {
				g.setColor( Color.black );
				eDraw.drawLabel(g);
			}
		}
		
		//Draws supports
		g.setColor(model.getState().supportColor);
		ListIterator sts = supports.listIterator();
		while(sts.hasNext()) {
			draw = (Draw)sts.next();
			no = (Node)draw.getRepresents();
			IPoint3d p3 = no.getCoord();
			draw.setLocation(da.getViewPoint( new Point2D.Double(p3.x, p3.y) ));
			draw.setScale(supportScale);
			draw.draw(g);
		}
		
		//Draws liberations
		g.setColor(model.getState().supportColor);
		ListIterator libs = liberations.listIterator();
		while(libs.hasNext()) {
			draw = (Draw)libs.next();
			draw.setScale(supportScale);
			draw.draw(g);
		}
		
		//Draws initial equivalent nodal forces
		g.setColor(model.getState().iniEqForceColor);
		ListIterator ies = iniEqForces.listIterator();
		while(ies.hasNext()) {
			draw = (Draw)ies.next();
			draw.setScale(iniEqForceScale);
			draw.draw(g);
		}
		
		//Draws temperature changes
		g.setColor(model.getState().tempChangeColor);
		ListIterator tcs = tempChanges.listIterator();
		while(tcs.hasNext()) {
			draw = (Draw)tcs.next();
			draw.draw(g);
		}
		
		//Draws prescribed displacements
		g.setColor(model.getState().displaceColor);
		ListIterator dds = displaces.listIterator();
		while(dds.hasNext()) {
			draw = (Draw)dds.next();
			no = (Node)draw.getRepresents();
			IPoint3d p3 = no.getCoord();
			draw.setLocation(da.getViewPoint( new Point2D.Double(p3.x, p3.y) ));
			draw.setScale(displaceScale);
			draw.draw(g);
		}
		
		//Draws pre-strains
		g.setColor(model.getState().preStrainsColor);
		ListIterator pss = preStrains.listIterator();
		while(pss.hasNext()) {
			draw = (Draw)pss.next();
			draw.setScale(preStrainsScale);
			draw.draw(g);
		}
		
		//Draws springs
		g.setColor(model.getState().springColor);
		ListIterator sps = springs.listIterator();
		while(sps.hasNext()) {
			draw = (Draw)sps.next();
			no = (Node)draw.getRepresents();
			IPoint3d p3 = no.getCoord();
			draw.setLocation(da.getViewPoint( new Point2D.Double(p3.x, p3.y) ));
			draw.setScale(supportScale);
			draw.draw(g);
		}
		
		//Draws nodal loads
		g.setColor(model.getState().loadColor);
		ListIterator nls = nodalLoads.listIterator();
		while(nls.hasNext()) {
			draw = (Draw)nls.next();
			no = (Node)draw.getRepresents();
			IPoint3d p3 = no.getCoord();
			draw.setLocation(da.getViewPoint( new Point2D.Double(p3.x, p3.y) ));
			draw.setScale(loadScale);
			draw.draw(g);
		}
		
		//Draws nodes
		g.setColor(model.getState().pointColor);
		ListIterator pts = nodes.listIterator();
		while(pts.hasNext()) {
			draw = (Draw)pts.next();
			no = (Node)draw.getRepresents();
			if (model.getState().getViewNodeLabel())
				draw.setLabel(no.getLabel());
			else draw.setLabel("");
			if (model.getDiscreteModel().getGlobalAnalysisModel().getType().equals("PlaneTruss")){
				g.setColor(model.getState().pointColor);
				draw.setScale(nodeScale*2);
				draw.draw(g);
				Draw draw2 = (Draw)draw.clone();
				g.setColor(model.getState().getBackground());
				draw2.setScale(nodeScale*1);
				draw2.setSelected(false);
				draw2.setSelectable(false);
				draw2.draw(g);
			} else {
				draw.setScale(nodeScale*1);
				draw.draw(g);
			}
		}
		
		//Draws concentrated forces
		g.setColor(model.getState().loadColor);
		ListIterator cfs = concForces.listIterator();
		while(cfs.hasNext()) {
			draw = (Draw)cfs.next();
			draw.setScale(loadScale);
			draw.draw(g);
		}
		
		//Draws concentrated forces points
		g.setColor(model.getState().concForcePointColor);
		ListIterator cfps = concForcesPoints.listIterator();
		while(cfps.hasNext()) {
			draw = (Draw)cfps.next();
			draw.setScale(concForcePointScale);
			draw.draw(g);
		}
		
		//Draws distributed forces
		g.setColor(model.getState().distributedLoadColor);
		ListIterator dfs = distForces.listIterator();
		while(dfs.hasNext()) {
			draw = (Draw)dfs.next();
			draw.setScale(loadScale);
			draw.draw(g);
		}
		
//		Draws the gauss Marks
		//double gPNodeScale = model.getState().nodeScale;
		g.setColor(model.getState().pointColor);
		ListIterator gpts = this.gaussMarks.listIterator();
		while(gpts.hasNext()) {
			draw = (Draw)gpts.next();
			ip = (IntegrationPoint)draw.getRepresents();
			draw.setScale(nodeScale);
			draw.setLabel(ip.getLabel());
			draw.draw(g);
		}
		
	}
	
//*****************************************************************************
	
    public void fit() {
        
        //Calculating bounds
        if (nodes.size() >= 2){
            Point leftUp = new Point();
            Point rightDown = new Point();
            PointDraw po;
            ListIterator pts = nodes.listIterator();
            po = (PointDraw)pts.next();
            leftUp.x = po.getLocation().x;
            leftUp.y = po.getLocation().y;
            rightDown.x = po.getLocation().x;
            rightDown.y = po.getLocation().y;
            while (pts.hasNext()){
                po = (PointDraw)pts.next();
                if (po.getLocation().x < leftUp.x){
                    leftUp.x = po.getLocation().x;
                }
                if (po.getLocation().x > rightDown.x){
                    rightDown.x = po.getLocation().x;
                }
                if (po.getLocation().y < leftUp.y){
                    leftUp.y = po.getLocation().y;
                }
                if (po.getLocation().y > rightDown.y){
                    rightDown.y = po.getLocation().y;
                }
            }
			
            //Adding some border
            leftUp.x = leftUp.x - 15;
            leftUp.y = leftUp.y - 15;
            rightDown.x = rightDown.x + 15;
            rightDown.y = rightDown.y + 15;
            
            Point2D p1 = da.getWorldPoint(leftUp);
            Point2D p2 = da.getWorldPoint(rightDown);
            Rectangle2D r = new Rectangle2D.Double(p1.getX(), p2.getY(), p2.getX(), p1.getY());
            
			da.setZoom(r);
        }
    }
	
//*****************************************************************************
	
    public void add(Object obj) {
		
		if (obj instanceof SpringDraw) {
			SpringDraw sd = (SpringDraw)obj;
			Node no = (Node)sd.getRepresents();
			IPoint3d p3 = no.getCoord();
			sd.setLocation( da.getViewPoint(new Point2D.Double(p3.x, p3.y)) );
			springs.add(sd);
		}
		
		if (obj instanceof DisplaceDraw) {
			DisplaceDraw dd = (DisplaceDraw)obj;
			Node no = (Node)dd.getRepresents();
			IPoint3d p3 = no.getCoord();
			dd.setLocation( da.getViewPoint(new Point2D.Double(p3.x, p3.y)) );
			displaces.add(dd);
		}
		
		if (obj instanceof SupportDraw) {
			SupportDraw s = (SupportDraw)obj;
			Node no = (Node)s.getRepresents();
			if (no != null){
				IPoint3d p3 = no.getCoord();
				s.setLocation(da.getViewPoint( new Point2D.Double(p3.x, p3.y) ));
				supports.add(s);
			}
		}
		
		if (obj instanceof ArrowDraw) {
			ArrowDraw a = (ArrowDraw)obj;
			
			Object obj2 = a.getRepresents();
			if (obj2 instanceof Node) {
				Node no = (Node)a.getRepresents();
				if (no != null){
					IPoint3d p3 = no.getCoord();
					a.setLocation(da.getViewPoint( new Point2D.Double(p3.x, p3.y) ));
					nodalLoads.add(a);
				}
			}
			else if (obj2 instanceof FrameElement) {
				concForces.add(a);
			}
		}
		
	}
	
//*****************************************************************************
	
    public boolean contains(Point2D po) {
        Point p = da.getViewPoint(po);
        Draw draw;
        
        ListIterator pts = nodes.listIterator();
        while(pts.hasNext()) {
            draw = (Draw)pts.next();
            if (draw.contains(p)) {
                return true;
            }
        }
		ListIterator lns = felements.listIterator();
		while(lns.hasNext()) {
			draw = (Draw)lns.next();
			if (draw.contains(p)) {
				return true;
			}
		}
		ListIterator pes = pelements.listIterator();
		while(pes.hasNext()) {
			draw = (Draw)pes.next();
			if (draw.contains(p)) {
				return true;
			}
		}
        return false;
    }
	
//*****************************************************************************
	
    public boolean contains(Line2D l) {
        Point  p1 = da.getViewPoint(l.getP1());
        Point  p2 = da.getViewPoint(l.getP2());
        Draw draw;
        
        ListIterator lns = felements.listIterator();
        while(lns.hasNext()) {
            draw = (Draw)lns.next();
            if (draw.contains(p1) && draw.contains(p2)) {
                return true;
            }
        }
        ListIterator pes = pelements.listIterator();
        while(pes.hasNext()) {
            draw = (Draw)pes.next();
            if (draw.contains(p1) && draw.contains(p2)) {
                return true;
            }
        }
		
        return false;
    }
	
//*****************************************************************************
	
    public Point pick(Point p) {
        
        Draw draw;
		
        ListIterator pts = nodes.listIterator();
        while(pts.hasNext()) {
            draw = (Draw)pts.next();
            if (draw.contains(p)) {
                return draw.getLocation();
            }
        }
		ListIterator lns = felements.listIterator();
		while(lns.hasNext()) {
			draw = (Draw)lns.next();
			if (draw.contains(p)) {
				return draw.getLocation();
			}
		}
		ListIterator pes = pelements.listIterator();
		while(pes.hasNext()) {
			draw = (Draw)pes.next();
			if (draw.contains(p)) {
				return draw.getLocation();
			}
		}
        return p;
    }
	
//*****************************************************************************
	
    public void remove(Object obj) {
        /*
		if (obj instanceof Node) {
            fmodel.remove((Node)obj);
        }
        if (obj instanceof Element) {
            fmodel.remove((Element)obj);
        }
        if (obj instanceof Material) {
            fmodel.remove((Material)obj);
        }
        if (obj instanceof CrossSection) {
            fmodel.remove((CrossSection)obj);
        }
		if (obj instanceof AnalysisModel) {
            fmodel.remove((AnalysisModel)obj);
        }
		this.compose();
		*/
		
    }
	
//*****************************************************************************
	
    public List removeSelection() {
        
        ArrayList<Object> sel = new ArrayList<Object>();
		PointDraw pd;
        LineDraw ld;
        int index;
        
        ListIterator pts = nodes.listIterator();
        while(pts.hasNext()) {
            pd = (PointDraw)pts.next();
            if (pd.isSelected()) {
				Node p = (Node)pd.getRepresents();
				index = selection.indexOf(pd.getRepresents());
				selection.remove(index);
                fmodel.remove(p);
                sel.add(p);
            }
        }
		ListIterator lns = felements.listIterator();
		while(lns.hasNext()) {
			ld = (LineDraw)lns.next();
			if (ld.isSelected()){
				Element l = (Element)ld.getRepresents();
				index = selection.indexOf(ld.getRepresents());
				selection.remove(index);
				fmodel.remove(l);
				sel.add(l);
			}
		}
		ListIterator pes = pelements.listIterator();
		while(pes.hasNext()) {
/**/			ld = (LineDraw)pes.next();
			if (ld.isSelected()){
				Element l = (Element)ld.getRepresents();
				index = selection.indexOf(ld.getRepresents());
				selection.remove(index);
				fmodel.remove(l);
				sel.add(l);
			}
		}
		this.compose();
		
		return sel;
		
    }
    
//*****************************************************************************
	
    public void removeAll() {
        nodes.clear();
		felements.clear();
		pelements.clear();
		
		supports.clear();
		nodalLoads.clear();
		springs.clear();
		displaces.clear();
		
		localAxis.clear();
		concForces.clear();
		concForcesPoints.clear();
		liberations.clear();
		preStrains.clear();
		distForces.clear();
		tempChanges.clear();
		iniEqForces.clear();
		elasticConnections.clear();
		
    }
	
//*****************************************************************************
	
	public void unSelectPoints() {
        Draw draw;
        
        ListIterator pts = nodes.listIterator();
        while(pts.hasNext()) {
            draw = (Draw)pts.next();
            draw.setSelected(false);
        }
	}
	
//*****************************************************************************
	
    public ArrayList getSelection() {
        return selection;
    }
	
//*****************************************************************************
	
    public Object get(Point2D po) {
		Point location = da.getViewPoint(po);
        Draw draw;
        
        ListIterator pts = nodes.listIterator();
        while(pts.hasNext()) {
            draw = (Draw)pts.next();
            if (draw.contains(location)) {
                return draw.getRepresents();
            }
        }
		ListIterator lns = felements.listIterator();
		while(lns.hasNext()) {
			draw = (Draw)lns.next();
			if (draw.contains(location)){
				return draw.getRepresents();
			}
		}
		ListIterator pes = pelements.listIterator();
		while(pes.hasNext()) {
			draw = (Draw)pes.next();
			if (draw.contains(location)){
				return draw.getRepresents();
			}
		}
		
        return null;
    }
    
//*****************************************************************************
	
    public boolean isSelected() {
        Draw draw;
        
        ListIterator pts = nodes.listIterator();
        while(pts.hasNext()) {
            draw = (Draw)pts.next();
            if (draw.isSelected()) {
                return true;
            }
        }
		ListIterator lns = felements.listIterator();
		while(lns.hasNext()) {
			draw = (Draw)lns.next();
			if (draw.isSelected()){
				return true;
			}
		}
		ListIterator pes = pelements.listIterator();
		while(pes.hasNext()) {
			draw = (Draw)pes.next();
			if (draw.isSelected()){
				return true;
			}
		}
		
		return false;
	}
	
//*****************************************************************************
	
	public void compose() {
		
		this.removeAll();
		
		//Filling the "nodes", "supports", "springs" and "nodalLoads" lists
		ListIterator femnodes = fmodel.getNodesList().listIterator();
		
		Node node;
		Point2D po;
		Point p;
		while (femnodes.hasNext()) {
			node = (Node)femnodes.next();
			po = new Point2D.Double(node.getCoord().x, node.getCoord().y);
			p = da.getViewPoint(po);
			nodes.add(new PointDraw(p, node));
			
			//adding supports and springs
			boolean Rdx = node.getRestraint(0);
			boolean Rdy = node.getRestraint(1);
			boolean Rrz = node.getRestraint(5);
			
			double Kx = node.getSpring(0);
			double Ky = node.getSpring(1);
			double Krz = node.getSpring(5);
			
			if (Rdx && !Rdy && !Rrz && Kx==0 && Ky==0 && Krz==0) {
				Draw draw = new SupportDraw.Y();
				draw.setRepresents(node);
				draw.setAngle(-Math.toRadians(90) + node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && Rdy && !Rrz && Kx==0 && Ky==0 && Krz==0) {
				Draw draw = new SupportDraw.Y();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && !Rdy && Rrz && Kx==0 && Ky==0 && Krz==0) {
				Draw draw = new SupportDraw.Z();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (Rdx && Rdy && !Rrz && Kx==0 && Ky==0 && Krz==0) {
				Draw draw = new SupportDraw.XY();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (Rdx && !Rdy && Rrz && Kx==0 && Ky==0 && Krz==0) {
				Draw draw = new SupportDraw.YZ();
				draw.setRepresents(node);
				draw.setAngle(-Math.toRadians(90) + node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && Rdy && Rrz && Kx==0 && Ky==0 && Krz==0) {
				Draw draw = new SupportDraw.YZ();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (Rdx && Rdy && Rrz && Kx==0 && Ky==0 && Krz==0) {
				Draw draw = new SupportDraw.XYZ();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && !Rdy && !Rrz && Kx!=0 && Ky==0 && Krz==0) {
				Draw draw = new SpringDraw.Dx();
				draw.setRepresents(node);
				draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && !Rdy && !Rrz && Kx==0 && Ky!=0 && Krz==0) {
				Draw draw = new SpringDraw.Dy();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && !Rdy && !Rrz && Kx==0 && Ky==0 && Krz!=0) {
				Draw draw = new SpringDraw.Rz();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && !Rdy && !Rrz && Kx!=0 && Ky!=0 && Krz==0) {
				Draw draw = new SpringDraw.Dx();
				draw.setRepresents(node);
				draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SpringDraw.Dy();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && !Rdy && !Rrz && Kx!=0 && Ky==0 && Krz!=0) {
				Draw draw = new SpringDraw.Dx();
				draw.setRepresents(node);
				draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SpringDraw.Rz();
				draw.setRepresents(node);
				draw.setAngle(-Math.toRadians(90) + node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && !Rdy && !Rrz && Kx==0 && Ky!=0 && Krz!=0) {
				Draw draw = new SpringDraw.Dy();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw); 
				draw = new SpringDraw.Rz();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && !Rdy && !Rrz && Kx!=0 && Ky!=0 && Krz!=0) {
				Draw draw = new SpringDraw.Dx();
				draw.setRepresents(node);
				draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SpringDraw.Dy();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SpringDraw.Rz();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (Rdx && !Rdy && !Rrz && Kx==0 && Ky!=0 && Krz==0) {
				Draw draw = new SupportDraw.Y();
				draw.setRepresents(node);
				draw.setAngle(-Math.toRadians(90) + node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SpringDraw.Dy();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (Rdx && !Rdy && !Rrz && Kx==0 && Ky==0 && Krz!=0) {
				Draw draw = new SupportDraw.Y();
				draw.setRepresents(node);
				draw.setAngle(-Math.toRadians(90) + node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SpringDraw.Rz();
				draw.setRepresents(node);
				draw.setAngle(-Math.toRadians(90) + node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && Rdy && !Rrz && Kx==0 && Ky==0 && Krz!=0) {
				Draw draw = new SupportDraw.Y();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SpringDraw.Rz();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && Rdy && !Rrz && Kx!=0 && Ky==0 && Krz==0) {
				Draw draw = new SpringDraw.Dx();
				draw.setRepresents(node);
				draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SupportDraw.Y();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && !Rdy && Rrz && Kx!=0 && Ky==0 && Krz==0) {
				Draw draw = new SpringDraw.Dx();
				draw.setRepresents(node);
				draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SupportDraw.Z();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && !Rdy && Rrz && Kx==0 && Ky!=0 && Krz==0) {
				Draw draw = new SpringDraw.Dy();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SupportDraw.Z();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (Rdx && Rdy && !Rrz && Kx==0 && Ky==0 && Krz!=0) {
				Draw draw = new SupportDraw.XY();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SpringDraw.Rz();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (Rdx && !Rdy && Rrz && Kx==0 && Ky!=0 && Krz==0) {
				Draw draw = new SpringDraw.Dy();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SupportDraw.YZ();
				draw.setRepresents(node);
				draw.setAngle(-Math.toRadians(90) + node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && Rdy && Rrz && Kx!=0 && Ky==0 && Krz==0) {
				Draw draw = new SpringDraw.Dx();
				draw.setRepresents(node);
				draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SupportDraw.YZ();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (Rdx && !Rdy && !Rrz && Kx==0 && Ky!=0 && Krz!=0) {
				Draw draw = new SupportDraw.Y();
				draw.setRepresents(node);
				draw.setAngle(-Math.toRadians(90) + node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SpringDraw.Dy();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SpringDraw.Rz();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && Rdy && !Rrz && Kx!=0 && Ky==0 && Krz!=0) {
				Draw draw = new SpringDraw.Dx();
				draw.setRepresents(node);
				draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SupportDraw.Y();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SpringDraw.Rz();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			} else if (!Rdx && !Rdy && Rrz && Kx!=0 && Ky!=0 && Krz==0) {
				Draw draw = new SpringDraw.Dx();
				draw.setRepresents(node);
				draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SpringDraw.Dy();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				draw = new SupportDraw.Z();
				draw.setRepresents(node);
				draw.setAngle(node.getAngle()*Math.PI/180);
				this.add(draw);
				
			}//end of adding supports
			
			//Adding nodal loads
			//Fx loads
			if (node.getForce(0) != 0) {
				Draw draw = new ArrowDraw.Out();
				draw.setRepresents(node);
				((ArrowDraw)draw).setValue(node.getForce(0));
				draw.setAngle(node.getAngle()*Math.PI/180);
				//draw.setLabel(String.valueOf(node.getForce(0)));
				this.add(draw);
			}
			//Fy loads
			if (node.getForce(1) != 0) {
				Draw draw = new ArrowDraw.Out();
				draw.setRepresents(node);
				((ArrowDraw)draw).setValue(node.getForce(1));
				draw.setAngle(Math.toRadians(90) + node.getAngle()*Math.PI/180);
				//draw.setLabel(String.valueOf(node.getForce(1)));
				this.add(draw);
			}
			//Mz loads
			if (node.getForce(5) != 0) {
				Draw draw = new ArrowDraw.AntiClockwise();
				draw.setRepresents(node);
				((ArrowDraw)draw).setValue(node.getForce(5));
				//draw.setLabel(String.valueOf(node.getForce(5)));
				this.add(draw);
			}
			//End of adding nodalLoads
			
			//Adding prescribed displacement
			double Ddx = node.getPreDisplacement(0);
			double Ddy = node.getPreDisplacement(1);
			double Drz = node.getPreDisplacement(5);
			if (Ddx!=0) {
				Draw draw = new DisplaceDraw.Linear();
				draw.setRepresents(node);
				draw.setAngle(Math.toRadians(node.getAngle()));
				((DisplaceDraw)draw).setValue(Ddx);
				this.add(draw);
			}
			if (Ddy!=0) {
				Draw draw = new DisplaceDraw.Linear();
				draw.setRepresents(node);
				draw.setAngle(Math.toRadians(node.getAngle() +90));
				((DisplaceDraw)draw).setValue(Ddy);
				this.add(draw);
			}
			if (Drz!=0) {
				Draw draw = new DisplaceDraw.Angular();
				draw.setRepresents(node);
				((DisplaceDraw)draw).setValue(Drz);
				this.add(draw);
			}//end of add prescribed displacement
			
		}
		
		//Filling the "felements", "localAxis", "liberations", "concForces", "concForcesPoints",
		// "preStrains", "distForces", "tempChanges", "iniEqForces" and "elasticConnections" lists
		ListIterator elms = fmodel.getElementsList().listIterator();
		Element elm;
		Point p1;
		Point p2;
		while (elms.hasNext()) {
			elm = (Element)elms.next();
			
			if (elm instanceof FrameElement) {
				FrameElement felm = (FrameElement)elm;
				
				node = felm.getInitialNode();
				po = new Point2D.Double(node.getCoord().x, node.getCoord().y);
				p1 = da.getViewPoint(po);
				node = felm.getFinalNode();
				po = new Point2D.Double(node.getCoord().x, node.getCoord().y);
				p2 = da.getViewPoint(po);
				felements.add(new LineDraw(p1, p2, felm));
				
				//Setting the variables in (initial node) and fn (final node)
				Node in = felm.getInitialNode();
				Node fn = felm.getFinalNode();
				
				//Calculating the angle between local axis and global axis and its sine and cosine
				double elmAngle = 0;
				Point2D in2d = new Point2D.Double(in.getCoord().x, in.getCoord().y);
				Point2D fn2d = new Point2D.Double(fn.getCoord().x, fn.getCoord().y);
				in2d = da.getViewPoint(in2d);
				fn2d = da.getViewPoint(fn2d);
				
				if (fn.getCoord().x > in.getCoord().x) {
					elmAngle = -Math.atan((fn2d.getY() - in2d.getY()) / (fn2d.getX() - in2d.getX()));
				} else if (fn.getCoord().x < in.getCoord().x) {
					elmAngle = -Math.atan((fn2d.getY() - in2d.getY()) / (fn2d.getX() - in2d.getX())) + Math.toRadians(180);
				} else if ((fn.getCoord().x==in.getCoord().x) && (fn.getCoord().y>in.getCoord().y)) {
					elmAngle = Math.toRadians(90);
				} else if ((fn.getCoord().x==in.getCoord().x) && (fn.getCoord().y<in.getCoord().y)) {
					elmAngle = Math.toRadians(-90);
				}
				
				//Adding Local Axis
				Draw draw2 = new AxisDraw();
				draw2.setRepresents(felm);
				draw2.setAngle(elmAngle);
				draw2.setLocation(p1);
				((AxisDraw)draw2).setLabel1("X");
				((AxisDraw)draw2).setLabel2("Y");
				localAxis.add(draw2);
				
				//Adding liberations
				//Dx1 liberation
				if (felm.getLiberation(0) && !felm.getLiberation(1) && !felm.getLiberation(5)){
					Draw draw = new LiberationDraw.X();
					draw.setRepresents(elm);
					draw.setAngle(elmAngle);
					draw.setLocation(p1);
					((LiberationDraw)draw).setModelState(model.getState());
					liberations.add(draw);
				}
				//Dy1 liberation
				if (!felm.getLiberation(0) && felm.getLiberation(1) && !felm.getLiberation(5)){
					Draw draw = new LiberationDraw.Y();
					draw.setRepresents(elm);
					draw.setAngle(elmAngle);
					draw.setLocation(p1);
					((LiberationDraw)draw).setModelState(model.getState());
					liberations.add(draw);
				}
				//Rz1 liberation
				if (!felm.getLiberation(0) && !felm.getLiberation(1) && felm.getLiberation(5)){
					Draw draw = new LiberationDraw.Z();
					draw.setRepresents(elm);
					draw.setAngle(elmAngle);
					draw.setLocation(p1);
					((LiberationDraw)draw).setModelState(model.getState());
					liberations.add(draw);
				}
				//Dx1 and Dy1 liberation
				if (felm.getLiberation(0) && felm.getLiberation(1) && !felm.getLiberation(5)){
					Draw draw = new LiberationDraw.XY();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle);
					draw.setLocation(p1);
					((LiberationDraw)draw).setModelState(model.getState());
					liberations.add(draw);
				}
				//Dx1 and Rz1 liberation
				if (felm.getLiberation(0) && !felm.getLiberation(1) && felm.getLiberation(5)){
					Draw draw = new LiberationDraw.XZ();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle);
					draw.setLocation(p1);
					((LiberationDraw)draw).setModelState(model.getState());
					liberations.add(draw);
				}
				//Dy1 and Rz1 liberation
				if (!felm.getLiberation(0) && felm.getLiberation(1) && felm.getLiberation(5)){
					Draw draw = new LiberationDraw.YZ();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle);
					draw.setLocation(p1);
					((LiberationDraw)draw).setModelState(model.getState());
					liberations.add(draw);
				}
				//Dx1, Dy1 and Rz1 liberation
				if (felm.getLiberation(0) && felm.getLiberation(1) && felm.getLiberation(5)){
					Draw draw = new LiberationDraw.XYZ();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle);
					draw.setLocation(p1);
					((LiberationDraw)draw).setModelState(model.getState());
					liberations.add(draw);
				}
				
				//Dx2 liberation
				if (felm.getLiberation(6) && !felm.getLiberation(7) && !felm.getLiberation(11)){
					Draw draw = new LiberationDraw.X();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle + Math.toRadians(180));
					draw.setLocation(p2);
					((LiberationDraw)draw).setModelState(model.getState());
					liberations.add(draw);
				}
				//Dy2 liberation
				if (!felm.getLiberation(6) && felm.getLiberation(7) && !felm.getLiberation(11)){
					Draw draw = new LiberationDraw.Y();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle + Math.toRadians(180));
					draw.setLocation(p2);
					((LiberationDraw)draw).setModelState(model.getState());
					liberations.add(draw);
				}
				//Rz2 liberation
				if (!felm.getLiberation(6) && !felm.getLiberation(7) && felm.getLiberation(11)){
					Draw draw = new LiberationDraw.Z();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle + Math.toRadians(180));
					draw.setLocation(p2);
					((LiberationDraw)draw).setModelState(model.getState());
					liberations.add(draw);
				}
				//Dx2 and Dy2 liberation
				if (felm.getLiberation(6) && felm.getLiberation(7) && !felm.getLiberation(11)){
					Draw draw = new LiberationDraw.XY();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle + Math.toRadians(180));
					draw.setLocation(p2);
					((LiberationDraw)draw).setModelState(model.getState());
					liberations.add(draw);
				}
				//Dx2 and Rz2 liberation
				if (felm.getLiberation(6) && !felm.getLiberation(7) && felm.getLiberation(11)){
					Draw draw = new LiberationDraw.XZ();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle + Math.toRadians(180));
					draw.setLocation(p2);
					((LiberationDraw)draw).setModelState(model.getState());
					liberations.add(draw);
				}
				//Dy2 and Rz2 liberation
				if (!felm.getLiberation(6) && felm.getLiberation(7) && felm.getLiberation(11)){
					Draw draw = new LiberationDraw.YZ();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle + Math.toRadians(180));
					draw.setLocation(p2);
					((LiberationDraw)draw).setModelState(model.getState());
					liberations.add(draw);
				}
				//Dx2, Dy2 and Rz2 liberation
				if (felm.getLiberation(6) && felm.getLiberation(7) && felm.getLiberation(11)){
					Draw draw = new LiberationDraw.XYZ();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle + Math.toRadians(180));
					draw.setLocation(p2);
					((LiberationDraw)draw).setModelState(model.getState());
					liberations.add(draw);
				}
				//End of adding liberations
				
				//Adding elastic connections
				if (felm.getMaterial() instanceof MSpring) {
					//MSpring mat = (MSpring)felm.getMaterial();
				}
				//End of adding elastic connections
				
				//Adding concentrated forces
				ListIterator cf = felm.getElmPointForcesList().listIterator();
				while (cf.hasNext()) {
					PointForce force = (PointForce)cf.next();
					
					//Setting the application point of this concentrated force
					double cos2 = (fn.getCoord().x - in.getCoord().x) / felm.getLength();
					double sin2 = (fn.getCoord().y - in.getCoord().y) / felm.getLength();
					
					double d = force.getCoord().x;
					double x1 = in.getCoord().x + d*cos2;
					double y1 = in.getCoord().y + d*sin2;
					
					po = new Point2D.Double(x1, y1);
					p = da.getViewPoint(po);
					concForcesPoints.add(new PointDraw(p, felm));
					
					//Fx loads
					if (force.getForce(0) != 0) {
						ArrowDraw draw = new ArrowDraw.Out();
						draw.setRepresents(felm);
						((ArrowDraw)draw).setValue(force.getForce(0));
						draw.setAngle(elmAngle);
						draw.setLocation(da.getViewPoint(new Point2D.Double(x1, y1)));
						//draw.setLabel(String.valueOf(force.getForce(0)));
						concForces.add(draw);
					}
					//Fy loads
					if (force.getForce(1) != 0) {
						Draw draw = new ArrowDraw.Out();
						draw.setRepresents(felm);
						((ArrowDraw)draw).setValue(force.getForce(1));
						double forceAngle = elmAngle + Math.toRadians(90);
						draw.setAngle(forceAngle);
						draw.setLocation(da.getViewPoint(new Point2D.Double(x1, y1)));
						//draw.setLabel(String.valueOf(force.getForce(1)));
						this.add(draw);
					}
					//Mz loads
					if (force.getForce(5) != 0) {
						Draw draw = new ArrowDraw.AntiClockwise();
						draw.setRepresents(felm);
						((ArrowDraw)draw).setValue(force.getForce(5));
						draw.setLocation(da.getViewPoint(new Point2D.Double(x1, y1)));
						this.add(draw);
					}
				}//end of adding conc forces
				
				//Adding pre-strains
				if (felm.getElmPreDisplacement(0) != 0){
					Draw draw = new DisplaceDraw.Linear();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle);
					draw.setLocation(p1);
					((DisplaceDraw)draw).setValue(felm.getElmPreDisplacement(0));
					preStrains.add(draw);
				}
				if (felm.getElmPreDisplacement(1) != 0){
					Draw draw = new DisplaceDraw.Linear();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle + Math.toRadians(90));
					draw.setLocation(p1);
					((DisplaceDraw)draw).setValue(felm.getElmPreDisplacement(1));
					preStrains.add(draw);
				}
				if (felm.getElmPreDisplacement(5) != 0){
					Draw draw = new DisplaceDraw.Angular();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle);
					draw.setLocation(p1);
					((DisplaceDraw)draw).setValue(felm.getElmPreDisplacement(5));
					preStrains.add(draw);
				}
				if (felm.getElmPreDisplacement(6) != 0){
					Draw draw = new DisplaceDraw.Linear();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle);
					draw.setLocation(p2);
					((DisplaceDraw)draw).setValue(felm.getElmPreDisplacement(6));
					preStrains.add(draw);
				}
				if (felm.getElmPreDisplacement(7) != 0){
					Draw draw = new DisplaceDraw.Linear();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle + Math.toRadians(90));
					draw.setLocation(p2);
					((DisplaceDraw)draw).setValue(felm.getElmPreDisplacement(7));
					preStrains.add(draw);
				}
				if (felm.getElmPreDisplacement(11) != 0){
					Draw draw = new DisplaceDraw.Angular();
					draw.setRepresents(felm);
					draw.setAngle(elmAngle);
					draw.setLocation(p2);
					((DisplaceDraw)draw).setValue(felm.getElmPreDisplacement(11));
					preStrains.add(draw);
				}
				//end of adding pre-strains
				
				//Adding initial equivalent nodal forces
				if (felm.getInitialNodalForce(0) != 0) {
					Draw draw = new ArrowDraw.Out();
					draw.setRepresents(felm);
					((ArrowDraw)draw).setValue(felm.getInitialNodalForce(0));
					draw.setAngle(elmAngle);
					draw.setLocation(p1);
					iniEqForces.add(draw);
				}
				if (felm.getInitialNodalForce(1) != 0) {
					Draw draw = new ArrowDraw.Out();
					draw.setRepresents(felm);
					((ArrowDraw)draw).setValue(felm.getInitialNodalForce(1));
					draw.setAngle(elmAngle + Math.toRadians(90));
					draw.setLocation(p1);
					iniEqForces.add(draw);
				}
				if (felm.getInitialNodalForce(5) != 0) {
					Draw draw = new ArrowDraw.AntiClockwise();
					draw.setRepresents(felm);
					((ArrowDraw)draw).setValue(felm.getInitialNodalForce(5));
					draw.setLocation(p1);
					iniEqForces.add(draw);
				}
				if (felm.getInitialNodalForce(6) != 0) {
					Draw draw = new ArrowDraw.Out();
					draw.setRepresents(felm);
					((ArrowDraw)draw).setValue(felm.getInitialNodalForce(6));
					draw.setAngle(elmAngle);
					draw.setLocation(p2);
					iniEqForces.add(draw);
				}
				if (felm.getInitialNodalForce(7) != 0) {
					Draw draw = new ArrowDraw.Out();
					draw.setRepresents(felm);
					((ArrowDraw)draw).setValue(felm.getInitialNodalForce(7));
					draw.setAngle(elmAngle + Math.toRadians(90));
					draw.setLocation(p2);
					iniEqForces.add(draw);
				}
				if (felm.getInitialNodalForce(11) != 0) {
					Draw draw = new ArrowDraw.AntiClockwise();
					draw.setRepresents(felm);
					((ArrowDraw)draw).setValue(felm.getInitialNodalForce(11));
					draw.setLocation(p2);
					iniEqForces.add(draw);
				}
				//End of adding initial equivalent nodal forces
				
				//Adding temperature changes
				if (felm.getDeltaTemp(0) != 0) {
					Draw draw = new StringDraw();
					draw.setRepresents(felm);
					((StringDraw)draw).setString("Ts = " + String.valueOf(felm.getDeltaTemp(0)));
					int x = (int) ((p1.getX() + p2.getX())/2);
					int y = (int) ((p1.getY() + p2.getY())/2);
					draw.setAngle(elmAngle);
					((StringDraw)draw).setCentre(new Point(x, y));
					draw.setLocation(new Point(x, y-6));
					tempChanges.add(draw);
				}
				if (felm.getDeltaTemp(1) != 0) {
					Draw draw = new StringDraw();
					draw.setRepresents(felm);
					((StringDraw)draw).setString("Tn = " + String.valueOf(felm.getDeltaTemp(1)));
					int x = (int) ((p1.getX() + p2.getX())/2);
					int y = (int) ((p1.getY() + p2.getY())/2);
					draw.setAngle(elmAngle);
					((StringDraw)draw).setCentre(new Point(x, y));
					draw.setLocation(new Point(x, y+4));
					tempChanges.add(draw);
				}
				if (felm.getDeltaTemp(2) != 0) {
					Draw draw = new StringDraw();
					draw.setRepresents(felm);
					((StringDraw)draw).setString("Ti = " + String.valueOf(felm.getDeltaTemp(2)));
					int x = (int) ((p1.getX() + p2.getX())/2);
					int y = (int) ((p1.getY() + p2.getY())/2);
					draw.setAngle(elmAngle);
					((StringDraw)draw).setCentre(new Point(x, y));
					draw.setLocation(new Point(x, y+14));
					tempChanges.add(draw);
				}
				//End of adding temperature changes
				
				//Adding distributed loads
				ListIterator dfs = felm.getElmLineForcesList().listIterator();
				while (dfs.hasNext()) {
					ElementForce force = (ElementForce)dfs.next();
					
					//Setting the application points of this distributed force
					double cos2 = (fn.getCoord().x - in.getCoord().x) / felm.getLength();
					double sin2 = (fn.getCoord().y - in.getCoord().y) / felm.getLength();
					
					double d1 = ((PointForce)force.getPointForcesList().get(0)).getCoord().x;
					double d2 = ((PointForce)force.getPointForcesList().get(1)).getCoord().x;
					double x1 = in.getCoord().x + d1*cos2;
					double y1 = in.getCoord().y + d1*sin2;
					double x2 = in.getCoord().x + d2*cos2;
					double y2 = in.getCoord().y + d2*sin2;
					
					//Setting the values of a, b, axvalue, bxvalue, ayvalue and byvalue
					double a = ((PointForce)force.getPointForcesList().get(0)).getCoord().x;
					double b = ((PointForce)force.getPointForcesList().get(1)).getCoord().x;
					double axvalue = ((PointForce)force.getPointForcesList().get(0)).getForce(0);
					double bxvalue = ((PointForce)force.getPointForcesList().get(1)).getForce(0);
					double ayvalue = ((PointForce)force.getPointForcesList().get(0)).getForce(1);
					double byvalue = ((PointForce)force.getPointForcesList().get(1)).getForce(1);
					
					//Fx loads
					if (axvalue != 0 || bxvalue != 0) {
						po = new Point2D.Double(x1, y1);
						Point pa = da.getViewPoint(po);
						po = new Point2D.Double(x2, y2);
						Point pb = da.getViewPoint(po);
						pa.y = pa.y + 5;
						pb.y = pb.y + 5;
						Draw draw = new LineArrowDraw.X();
						draw.setRepresents(felm);
						((LineArrowDraw)draw).setBase(new LineDraw(pa, pb));
						((LineArrowDraw)draw).setA(a);
						((LineArrowDraw)draw).setB(b);
						((LineArrowDraw)draw).setAValue(axvalue);
						((LineArrowDraw)draw).setBValue(bxvalue);
						//double forceAngle = elmAngle;
						draw.setAngle(Math.toRadians(0));
						draw.setLocation(pa);
						((LineArrowDraw)draw).setEndLocation(pb);
						distForces.add(draw);
					}
					//Fy loads
					if (ayvalue != 0 || byvalue != 0) {
						po = new Point2D.Double(x1, y1);
						Point pa = da.getViewPoint(po);
						po = new Point2D.Double(x2, y2);
						Point pb = da.getViewPoint(po);
						Draw draw = new LineArrowDraw.Y();
						draw.setRepresents(felm);
						((LineArrowDraw)draw).setBase(new LineDraw(pa, pb));
						((LineArrowDraw)draw).setA(a);
						((LineArrowDraw)draw).setB(b);
						((LineArrowDraw)draw).setAValue(ayvalue);
						((LineArrowDraw)draw).setBValue(byvalue);
						//double forceAngle = elmAngle;
						draw.setAngle(Math.toRadians(90));
						draw.setLocation(pa);
						((LineArrowDraw)draw).setEndLocation(pb);
						distForces.add(draw);
					}
				}//End of distributed loads
			}//end of felements
			
			//Filling the pelements list
			else if (elm instanceof ParametricElement) {
				//ParametricElement pelm = (ParametricElement)elm;
				ParElementDraw eDraw = new ParElementDraw(da,elm);
				pelements.add(eDraw);
				
				//Adding distributed loads
				ElementSide elmSide = new ElementSide((ParametricElement)elm);
				elmSide.mountSide();
				Side sd = (Side)elmSide.getSidesList().get(0);
				
				
				ListIterator lineForces = elm.getElmLineForcesList().listIterator();
				while (lineForces.hasNext()) {
					
					
				ElementForce force = (ElementForce)lineForces.next();
				
				PointForce pf1 = new PointForce();
				PointForce pf2 = new PointForce();
							
							if (sd.getNNodes()==2){
							
							pf1 = (PointForce)force.getPointForcesList().get(0);
							pf2 = (PointForce)force.getPointForcesList().get(1);
							
							}
							
							if (sd.getNNodes()==3){
								
								pf1 = (PointForce)force.getPointForcesList().get(0);
								pf2 = (PointForce)force.getPointForcesList().get(2);
								
							}
							
							if (sd.getNNodes()==4){
								
								pf1 = (PointForce)force.getPointForcesList().get(0);
								pf2 = (PointForce)force.getPointForcesList().get(3);
								
							}
							
							double Fx1 = pf1.getForce(0);
							double Fy1 = pf1.getForce(1);
							double Mz1 = pf1.getForce(5);
							double Fx2 = pf2.getForce(0);
							double Fy2 = pf2.getForce(1);
							double Mz2 = pf2.getForce(5);
							
							if (pf1.getLabel()!=null && pf2.getLabel()!=null){
								
														
							if ( Fx1!=0 || Fx2!=0 ) {
							//if ( Fx1!=0) {
								Point pt1 = da.getViewPoint( new Point2D.Double(pf1.getCoord().x, pf1.getCoord().y) );
								Point pt2 = da.getViewPoint( new Point2D.Double(pf2.getCoord().x, pf2.getCoord().y) );
								Draw draw = new ArrowLineDraw.X( pt1, pt2 );
								//Draw draw = new PointDraw( pt1);
								((ArrowLineDraw)draw).setAValue(Fx1);
								((ArrowLineDraw)draw).setBValue(Fx2);
								draw.setLabel( force.getLabel() );
								draw.setRepresents(elm);
								distForces.add(draw);
								//this.add(draw);
							}
					
							if ( Fy1!=0 || Fy2!=0 ) {
							//if ( Fy1!=0 ) {
								Point pt1 = da.getViewPoint( new Point2D.Double(pf1.getCoord().x, pf1.getCoord().y) );
								Point pt2 = da.getViewPoint( new Point2D.Double(pf2.getCoord().x, pf2.getCoord().y) );
								Draw draw = new ArrowLineDraw.Y( pt1, pt2 );
								//Draw draw = new PointDraw( pt1);
								((ArrowLineDraw)draw).setAValue(Fy1);
								((ArrowLineDraw)draw).setBValue(Fy2);
								draw.setLabel( force.getLabel() );
								draw.setRepresents(elm);
								distForces.add(draw);
								//this.add(draw);
							}
							
							if ( Mz1!=0 || Mz2!=0 ) {
							//if ( Mz1!=0 ) {
								Point pt1 = da.getViewPoint( new Point2D.Double(pf1.getCoord().x, pf1.getCoord().y) );
								Point pt2 = da.getViewPoint( new Point2D.Double(pf2.getCoord().x, pf2.getCoord().y) );
								Draw draw = new ArrowLineDraw.Z( pt1, pt2 );
								//Draw draw = new PointDraw( pt1);
								((ArrowLineDraw)draw).setAValue(Mz1);
								((ArrowLineDraw)draw).setBValue(Mz2);
								draw.setLabel( force.getLabel() );
								distForces.add(draw);
								//this.add(draw);
							}
						}	
						
						
				
							
	}//End of distributed loads
				
				ArrayList incid = elm.getIncidence();
				ListIterator nds = incid.listIterator();
				while(nds.hasNext()) {
					Node nd = (Node)nds.next();
					IPoint3d p3d = nd.getCoord();
					double angle = Math.atan2( (p3d.y-eDraw.getYMedium()), (p3d.x-eDraw.getXMedium()) );
					nd.setAngle(angle);
				}
				
				
			}//end of pelements
			
		}//end of elements
		
//		Compose the Gauss Point marks for parametric elements
		Point gP;
		ListIterator gElms = fmodel.getElementsList().listIterator();
        Element gelm;
        gaussMarks.clear();
		while (gElms.hasNext()) {
			gelm = (Element)gElms.next();
			if (gelm instanceof ParametricElement){
			    ParametricElement pelm = (ParametricElement)gelm;
				ListIterator ElmGaussPts = pelm.getIntegrationPointsList().listIterator();
				while (ElmGaussPts.hasNext()){
					IntegrationPoint ip = (IntegrationPoint)ElmGaussPts.next();
					IMatrix N = pelm.mountN(ip);
					IVector coords = pelm.mountCoords();
					IVector coord = N.mul(coords);
					gP = da.getViewPoint( new Point2D.Double(coord.getElement(0), coord.getElement(1)));
				    gaussMarks.add(new PointDraw(gP, ip));
					
				}
			}
		}
		
	}
	
//*****************************************************************************
}
